iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0

歐吼~昨天我們講完了CNN今天就接著來說RNN

  • RNN
  • 模型實作

RNN(循環神經網路)

循環神經網絡(RNN)是一種深度學習模型,主要用於處理序列數據,像是文本、語音、時間序列等,它的獨特之處在於允許信息在不同時間步之間互相傳遞,因此能夠捕捉到序列數據中的時間相關性。

RNN的基本結構包含一個或多個時間步,每個時間步處理序列中的一個元素,例如處理句子中的每個詞語等等,以下是RNN的一些重點概念:

循環結構:RNN的結構是循環的,它允許信息在不同時間步之間進行反饋,這代表模型在處理序列時可以保持記憶,並根據過去的輸入做出決策。

隱藏狀態:RNN在每個時間步都有一個隱藏狀態,這個狀態包含了過去時間步的信息,可以把它看作是模型內部的記憶,用來捕捉序列的上下文和時間相關性。

權重共享:RNN的不同時間步共享相同的權重,因此模型學習到的參數在整個序列中都是一致的。

這裡放上一張示意圖
https://ithelp.ithome.com.tw/upload/images/20230925/20163184VVMmAyYGhX.jpg
X1、X2、X3 表輸入數據序列的不同時間步。
RNN代表 RNN 單元,每個時間步都有一個。
H1、H2、H3 代表 RNN 單元在不同時間步生成的隱藏狀態。
Input 代表模型的輸入層,接收來自 X1、X2、X3 的輸入數據。
Output 代表模型的輸出層,產生預測或其他結果。
箭頭表示了數據的流動方向,輸入 X1、X2、X3 進入輸入層,然後通過 RNN 單元在每個時間步處理,生成相應的隱藏狀態 H1、H2、H3。模型的輸出可以基於這些隱藏狀態或者其他計算而產生。

這是簡化版 RNN 結構示意圖,RNN 還可以有更多的層和其他變體,但這個示意圖可以幫助你理解整體結構概念。


RNN通過反向傳播算法進行訓練,目標是最小化某種損失函數,使模型能夠預測序列中的下一個元素或執行其他序列相關任務,同時可以堆疊多個RNN層以增加模型的複雜性,這形成了深度循環神經網絡(Deep RNN)

同時因為RNN存在梯度消失問題,為了解決這個問題出現了一些變種模型,如長短期記憶網絡(LSTM)門控循環單元(GRU),它們引入了特殊的門控機制,以改進信息的傳遞和記憶能力。

RNN在多個領域有廣泛應用,包括自然語言處理、語音識別、時間序列預測等。然而它也存在一些問題,例如長期依賴性的建模和梯度消失問題(還會因時間久了前面輸入經計算過程逐漸被淡化)。為了應對這些問題,研究人員開發了更高級的模型,如LSTMGRU這些模型在處理序列數據時有更好的表現。

以上就是對於RNN的大致介紹,下面一樣讓我們來進入實作環節。


模型實作

這段程式碼是用於建立、訓練和評估一個簡單的RNN模型,下面我們會做情感分類任務,該任務是將IMDB電影評論分為正面和負面兩類。以下是對這段程式碼的詳細解釋

  • 引入必要的函式庫
import tensorflow as tf
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, SimpleRNN, Dense
from tensorflow.keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt
  • 設定參數
num_words = 10000      # 使用前10000個常見詞彙
maxlen = 200           # 截斷或填充評論的最大長度
embedding_dim = 64     # 嵌入層的維度
rnn_units = 32         # RNN隱層的維度

定義模型的結構和訓練過程。

  • 載入IMDB數據集並進行預處理
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=num_words)
x_train = pad_sequences(x_train, maxlen=maxlen)
x_test = pad_sequences(x_test, maxlen=maxlen)

這裡載入了IMDB數據集,並使用pad_sequences函數將序列填充或截斷為相同的長度,以確保它們具有相同的維度。

第一次應該會跑出下載畫面
https://ithelp.ithome.com.tw/upload/images/20230925/20163184NOWsaQ3g0k.jpg

  • 建立RNN模型
model = Sequential()
model.add(Embedding(input_dim=num_words, output_dim=embedding_dim, input_length=maxlen))
model.add(SimpleRNN(units=rnn_units, activation='relu'))
model.add(Dense(units=1, activation='sigmoid'))

這裡建立了一個序列模型,包括嵌入層、SimpleRNN層和全連接層,嵌入層將整數索引轉換為密集向量表示,SimpleRNN層用於處理序列數據,全連接層用於二元分類(正面或負面情感)。

  • 編譯模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)

在這裡老樣子選擇了優化器(adam)損失函數(binary_crossentropy)準確率(accuracy),還有上次所使用的early_stopping

  • 訓練模型
history = model.fit(x_train, y_train, epochs=10, batch_size=128, validation_split=0.2, callbacks=[early_stopping])

模型將訓練10個epoch,每個batch的大小為128,並使用前面定義的EarlyStopping回調函數。

  • 評估模型性能
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"測試準確率: {test_accuracy*100:.2f}%")

顯示準確率

  • 繪製Loss圖
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

最後一樣使用Matplotlib繪製了訓練和測試集的損失曲線。

https://ithelp.ithome.com.tw/upload/images/20230925/20163184xFwMZFU0mg.jpg


那麼以上就是今天的RNN模型,希望有幫助到你一點,中間有提到RNN的一些缺點,也說到因缺點而誕生變種LSTM,明天我們就以LSTM來做介紹,來了解他與純RNN的不同,並且我們明天讓我們的輸出視覺化一點,單純跑出準確率與Loss是不是太過無聊了,那今天就先到這邊,我們明天見~~


上一篇
【Day9】CNN卷積神經網絡 :基本概念到模型建構與訓練
下一篇
【Day11】變種RNN?:用LSTM進行情感分類的模型實作
系列文
「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言